//
//  LJUtility.m
//  Onskysell
//
//  Created by LJJ on 17/7/10.
//  Copyright © 2017年 cg. All rights reserved.
//

#import "LJUtility.h"
#import <sys/utsname.h>
#import <objc/runtime.h>
#import <objc/message.h>
#import <LocalAuthentication/LocalAuthentication.h>
#import <CommonCrypto/CommonDigest.h>
#import <WebKit/WebKit.h>

@implementation LJUtility
+(float)cellHeightOfContentView:(UIView *)contentView{
    NSLayoutConstraint *tempWidthConstraint =
    [NSLayoutConstraint constraintWithItem:contentView
                                 attribute:NSLayoutAttributeWidth
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute
                                multiplier:1.0
                                  constant:contentView.bounds.size.width];
    [contentView addConstraint:tempWidthConstraint];
    
    // Auto layout engine does its math
    CGSize fittingSize = [contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    
    [contentView removeConstraint:tempWidthConstraint];
    return fittingSize.height;
}

+(void)addMaskViewOnWindow
{
    UIView *maskView = [[UIView alloc] initWithFrame:KWindow.bounds];
    maskView.tag = 99999;
    maskView.backgroundColor = [UIColor blackColor];
    maskView.alpha = 0.3;
    [KWindow addSubview:maskView];
}

+(void)dismissMaskViewFromWindow
{
    for (UIView *v in KWindow.subviews) {
        if (v.tag == 99999) {
            [v removeFromSuperview];
        }
    }
}

+ (UIView *)getMaskViewOnWindow
{
    for (UIView *v in KWindow.subviews) {
        if (v.tag == 99999) {
            return v;
        }
    }
    return nil;
}

+ (NSString *)dictionaryToJson:(NSDictionary *)dic{
    
    NSString *jsonString = [[NSString alloc] init];
    
    if (dic == nil) {
        return @"";
    }
    NSError *parseError = nil;
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError];
    
    //    return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    if (!jsonData) {
        NSLog(@"Json ParseError: %@", parseError);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    //去掉空格回车
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    
    NSRange range = {0,jsonString.length};
    
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    
    NSRange range2 = {0,mutStr.length};
    
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    
    return mutStr;
    
}

+ (NSString *)arrayToJson:(NSArray *)arr {
    if (arr.count == 0) {
        return @"";
    }
    
    NSString *jsonString = [[NSString alloc] init];
    NSError *parseError = nil;
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:&parseError];
    
    //    return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    if (!jsonData) {
        NSLog(@"Json ParseError: %@", parseError);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    //去掉空格回车
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    
    NSRange range = {0,jsonString.length};
    
    [mutStr replaceOccurrencesOfString:@" "withString:@""options:NSLiteralSearch range:range];
    
    NSRange range2 = {0,mutStr.length};
    
    [mutStr replaceOccurrencesOfString:@"\n"withString:@""options:NSLiteralSearch range:range2];
    
    return mutStr;
    
}

+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
    if (jsonString == nil) {
        return nil;
    }
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    if(err) {
        NSLog(@"json解析失败：%@",err);
        return nil;
    }
    
    return dic;
    
}

+ (NSString *)urlEncodedString:(NSString *)str
{
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)str,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    
    return encodedString;
}

+ (NSString *)urlDecodedString:(NSString *)str
{
    NSString *decodedString=(__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)str, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    
    return decodedString;
}

+ (BOOL)isIphoneX
{
    // iPhoneX,XS
    if ([UIScreen mainScreen].bounds.size.width == 375 && [UIScreen mainScreen].bounds.size.height == 812) {
        return YES;
    }
    // iPhoneXS Max,XR
    if ([UIScreen mainScreen].bounds.size.width == 414 && [UIScreen mainScreen].bounds.size.height == 896) {
        return YES;
    }
    return NO;
}

//获得设备型号
+ (NSString *)getiPhoneType
{
    struct utsname systemInfo;
    
    uname(&systemInfo);
    
    NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
    
    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
    
    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
    
    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
    
    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
    
    if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
    
    if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
    
    if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
    
    if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
    
    if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
    
    if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
    
    if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
    
    if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
    
    if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
    
    if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
    
    if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
    
    if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
    
    if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
    
    if ([platform isEqualToString:@"iPod1,1"])   return @"iPod Touch 1G";
    
    if ([platform isEqualToString:@"iPod2,1"])   return @"iPod Touch 2G";
    
    if ([platform isEqualToString:@"iPod3,1"])   return @"iPod Touch 3G";
    
    if ([platform isEqualToString:@"iPod4,1"])   return @"iPod Touch 4G";
    
    if ([platform isEqualToString:@"iPod5,1"])   return @"iPod Touch 5G";
    
    if ([platform isEqualToString:@"iPad1,1"])   return @"iPad 1G";
    
    if ([platform isEqualToString:@"iPad2,1"])   return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,2"])   return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,3"])   return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,4"])   return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,5"])   return @"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad2,6"])   return @"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad2,7"])   return @"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad3,1"])   return @"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,2"])   return @"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,3"])   return @"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,4"])   return @"iPad 4";
    
    if ([platform isEqualToString:@"iPad3,5"])   return @"iPad 4";
    
    if ([platform isEqualToString:@"iPad3,6"])   return @"iPad 4";
    
    if ([platform isEqualToString:@"iPad4,1"])   return @"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,2"])   return @"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,3"])   return @"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,4"])   return @"iPad Mini 2G";
    
    if ([platform isEqualToString:@"iPad4,5"])   return @"iPad Mini 2G";
    
    if ([platform isEqualToString:@"iPad4,6"])   return @"iPad Mini 2G";
    
    if ([platform isEqualToString:@"i386"])      return @"iPhone Simulator";
    
    if ([platform isEqualToString:@"x86_64"])    return @"iPhone Simulator";
    
    return platform;
}

+ (UIView *)getStatusBar
{
    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    return statusBar;
}

+ (NSString *)getDateTimeString
{
    NSDateFormatter *formatter;
    NSString        *dateString;
    
    formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd_HH:mm:ss"];
    
    dateString = [formatter stringFromDate:[NSDate date]];
    
    return dateString;
}

+ (NSString *)randomStringWithLength:(int)len
{
    NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
    
    for (int i=0; i<len; i++) {
        [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random_uniform((int)[letters length])]];
    }
    
    return randomString;
}

#pragma mark - crash报告处理
+ (void)crashCollectAndReport
{
    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
    // 发送崩溃日志
    NSString *dataPath = [self getCrashDataPath];
    NSData *data = [NSData dataWithContentsOfFile:dataPath];
    if (data != nil) {
        //发送数据
        NSString *fileName = [NSString stringWithFormat:@"OnskysellCrashReport_%@.txt", [self getDateTimeString]];
        [self uploadFileToQNFilePath:dataPath fileName:fileName];
    }
}

+ (NSString *)getCrashDataPath
{
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *dataPath = [path stringByAppendingPathComponent:@"OnskysellCrashReport.txt"];
    return dataPath;
}

void UncaughtExceptionHandler(NSException *exception) {
    NSArray *arr = [exception callStackSymbols];//得到当前调用栈信息
    NSString *reason = [exception reason];//非常重要，就是崩溃的原因
    NSString *name = [exception name];//异常类型
    NSString *phoneVersion = [[UIDevice currentDevice] systemVersion];//系统版本
    NSString* phoneModel = [LJUtility getiPhoneType];//设备型号
    
    NSLog(@"iOS version:%@, phone:%@\nexception type:%@\n crash reason : %@ n call stack info : %@", phoneVersion, phoneModel, name, reason, arr);
    
    NSString *crashInfo = [NSString stringWithFormat:@"iOS version:%@, phoneType:%@\nexception type : %@ \n crash reason :\n %@ \n call stack info :\n %@", phoneVersion, phoneModel, name, reason, arr];
//    crashInfo = [crashInfo stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
//    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
//    NSString *dataPath = [path stringByAppendingPathComponent:@"OnskysellCrashReport.txt"];
    
    NSString *dataPath;
    //C调OC
    SEL sel = NSSelectorFromString(@"getCrashDataPath");
    if ([LJUtility.class respondsToSelector:sel]) {
        dataPath = ((id (*)(id, SEL))objc_msgSend)(LJUtility.class, sel);
        if (dataPath) {
            //保存崩溃信息
            [crashInfo writeToFile:dataPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
        }
    }
    
    
    /*
    //发送崩溃邮件
    NSString *crashLogInfo = [NSString stringWithFormat:@"iOS version:%@, phoneType:%@\nexception type : %@ \n crash reason :\n %@ \n call stack info :\n %@", phoneVersion, phoneModel, name, reason, arr];
    NSString *urlStr = [NSString stringWithFormat:@"mailto://%@?subject=OnskySell Crash report&body=Thank you for your cooperation to report crash!\n" "------------ crash detail ------------\n%@", CrashEmail, crashLogInfo];
    NSURL *url = [NSURL URLWithString:urlStr];
    [[UIApplication sharedApplication] openURL:url];
     */
}

+ (BOOL)deleteFileWithPath:(NSString *)path
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isDelete = [fileManager removeItemAtPath:path error:nil];
    if (isDelete) return YES;
    return NO;
}

//获取当前的截图
+ (UIImage *)getScreenshotImg
{
    //创建一个新的ImageContext来绘制截图，你没有必要去渲染一个完整分辨率的高清截图，使用ImageContext可以节约掉不少的计算量
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT), NO, 1);
    [[[UIApplication sharedApplication] keyWindow] drawViewHierarchyInRect:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) afterScreenUpdates:NO];
    //将ImageContext放入一个UIImage内然后清理掉这个ImageContext
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

+ (CGFloat)getStatusBarHeight
{
    return [self isIphoneX]?44:20;
}

+ (BOOL)theStringIsValid:(NSString *)string
{
    if (string && ![string isEqualToString:@""]) {
        return YES;
    }
    return NO;
}

+ (BOOL)theString:(NSString *)str containSting:(NSString *)string
{
    if (str && [str rangeOfString:string options:NSCaseInsensitiveSearch].location != NSNotFound) {
        return YES;
    }
    return NO;
}

+ (BOOL)theString:(NSString *)str absoluteContainSting:(NSString *)string
{
    if (str && [str rangeOfString:string options:NSLiteralSearch].location != NSNotFound) {
        return YES;
    }
    return NO;
}

+ (void)sendEmailTo:(NSString *)toEmail info:(NSString *)info
{
    //发送崩溃邮件
    NSString *urlStr = [NSString stringWithFormat:@"mailto://%@?%@", toEmail, info];
    NSURL *url = [NSURL URLWithString:urlStr];
    [[UIApplication sharedApplication] openURL:url];
}

+ (NSString *)getSupportFingerprintIdentifyResult
{
    LAContext *myContext = [[LAContext alloc] init];
    NSError *authError = nil;
    if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) return nil;
        
    NSString *errorMsg = [authError.userInfo objectForKey:@"NSLocalizedDescription"];
    switch (authError.code) {
        case LAErrorTouchIDNotEnrolled:
        {
            errorMsg = @"无法启动认证,因为touchID未注册指纹";
            break;
        }
        case LAErrorPasscodeNotSet:
        {
            errorMsg = @"无法启动认证,因为设备未设置密码";
            break;
        }
        default:
            break;
    }
    
    return errorMsg;
}

+ (void)toVerifyFingerprintWithResult:(FingerVerifyBlock)resultBlock isWithRightBtn:(BOOL)haveRightBtn
{
    LAContext *myContext = [[LAContext alloc] init];
    if (!haveRightBtn) {
        myContext.localizedFallbackTitle = @"";
    }
    else myContext.localizedFallbackTitle = @"输入密码";
    NSError *authError = nil;
    NSString *myLocalizedReasonString = @"需要验证您的指纹";
    
    // 判断设备是否支持指纹识别
    if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
        
        // 指纹识别只判断当前用户是否机主
        [myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                  localizedReason:myLocalizedReasonString
                            reply:^(BOOL success, NSError *error) {
                                if (success) {
                                    // User authenticated successfully, take appropriate action
                                    NSLog(@"指纹认证成功");
//                                    return nil;
                                    if (resultBlock) {
                                        resultBlock(nil);
                                    }
                                    
                                } else {
                                    // User did not authenticate successfully, look at error and take appropriate action
                                    NSLog(@"指纹认证失败，%@",error.description);
                                    // 错误码 error.code
                                    // -1: 连续三次指纹识别错误
                                    // -2: 在TouchID对话框中点击了取消按钮
                                    // -3: 在TouchID对话框中点击了输入密码按钮
                                    // -4: TouchID对话框被系统取消，例如按下Home或者电源键
                                    // -8: 连续五次指纹识别错误，TouchID功能被锁定，下一次需要输入系统密码
                                    NSString *errorMsg = @"指纹认证失败";
                                    switch (error.code) {
                                        case LAErrorAuthenticationFailed:
                                        {
                                            NSLog(@"连续三次指纹识别错误");
                                            errorMsg = @"连续三次指纹识别错误";
                                            break;
                                        }
                                        case LAErrorUserCancel:
                                        {
                                            NSLog(@"用户取消验证Touch ID");
                                            errorMsg = @"用户取消验证Touch ID";
                                            break;
                                        }
                                        case LAErrorUserFallback:
                                        {
                                            NSLog(@"用户选择输入密码");
                                            errorMsg = @"用户选择输入密码";
//                                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
//                                                NSLog(@"用户选择输入密码，切换主线程处理");
//                                            }];
                                            break;
                                        }
                                        case LAErrorSystemCancel:
                                        {
                                            NSLog(@"系统取消授权，例如其他APP切入");
                                            errorMsg = @"系统取消授权，例如其他APP切入";
                                            break;
                                        }
                                        case LAErrorPasscodeNotSet:
                                        {
                                            NSLog(@"系统未设置密码");
                                            errorMsg = @"系统未设置密码";
                                            break;
                                        }
                                        case LAErrorTouchIDNotAvailable:
                                        {
                                            NSLog(@"设备Touch ID不可用，例如未打开");
                                            errorMsg = @"设备Touch ID不可用，例如未打开";
                                            break;
                                        }
                                        case LAErrorTouchIDNotEnrolled:
                                        {
                                            NSLog(@"设备Touch ID不可用，用户未录入");
                                            errorMsg = @"设备Touch ID不可用，用户未录入";
                                            break;
                                        }
                                        default:
                                        {
//                                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
//                                                NSLog(@"其他情况，切换主线程处理");
//                                            }];
                                            break;
                                        }
                                    }
                                    
                                    if (resultBlock) {
                                        resultBlock(errorMsg);
                                    }
                                }
                            }];
        
    } else {//不支持指纹识别
        // Could not evaluate policy; look at authError and present an appropriate message to user
        NSLog(@"TouchID设备不可用");
        // TouchID没有设置指纹
        // 关闭密码（系统如果没有设置密码TouchID无法启用）
        NSString *errorMsg = [authError.userInfo objectForKey:@"NSLocalizedDescription"];
        switch (authError.code) {
            case LAErrorTouchIDNotEnrolled:
            {
                errorMsg = @"无法启动认证,因为touchID未注册指纹";
                break;
            }
            case LAErrorPasscodeNotSet:
            {
                errorMsg = @"无法启动认证,因为设备未设置密码";
                break;
            }
            case -8:
            {
                errorMsg = @"指纹验证错误次数过多,被锁定";
                break;
            }
            default:
                break;
        }
        
        if (resultBlock) {
            resultBlock(errorMsg);
        }
    }
}

+ (NSString *)getTimeStampString
{
    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] * 1000;
    NSString *timeStr = [NSString stringWithFormat:@"%2f",interval];
    return timeStr;
}

+ (NSString*)md5:(NSString*)str {
    const char *cStr = [str UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, (double)strlen(cStr), result );
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}

+ (void)clearWKWebMemoryDiskCache
{
    //wkweb
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
        
        NSSet *websiteDataTypes = [NSSet setWithArray:@[
                                                        WKWebsiteDataTypeDiskCache,
                                                        WKWebsiteDataTypeOfflineWebApplicationCache,
                                                        WKWebsiteDataTypeMemoryCache,
                                                        WKWebsiteDataTypeLocalStorage,
                                                        //WKWebsiteDataTypeCookies,
                                                        //WKWebsiteDataTypeSessionStorage,
                                                        WKWebsiteDataTypeIndexedDBDatabases,
                                                        WKWebsiteDataTypeWebSQLDatabases
                                                        ]];
        
        
        //        NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
        NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
        [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
            
        }];
    } else {
        //        NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        //        NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
        //        NSError *errors;
        //        [[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
    }
}

+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size {
    if (!color ||
        size.width <= 0 ||
        size.height <= 0) return nil;
    
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContextWithOptions(rect.size,NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
@end
